package com.src.xyzk_personal.EOL;

import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Random;

import com.src.xyzk_personal.config.Common;
import com.src.xyzk_personal.config.Commonfunc;

import android.util.Log;

public class EolFunction {
	private static String TAG = "EolFunction";
	private static int [] crc32_table = new int[256];
	//产生PIN码
	public static void CreatePinCode(byte [] vin, byte [] Pin,int Psize)
	{
		//第一步，生成PIN
		Pin[0] = (byte) (vin[1] ^ vin[5] ^ vin[9]  ^ vin[13]);
		Pin[1] = (byte) (vin[2] ^ vin[6] ^ vin[10] ^ vin[14]);
		Pin[2] = (byte) (vin[3] ^ vin[7] ^ vin[11] ^ vin[15]);
		Pin[3] = (byte) (vin[4] ^ vin[8] ^ vin[12] ^ vin[16]);
	}
	//产生ESK
	public static void CreateESKCode(byte [] esk)
	{
		for(int i = 0 ; i < 16; i ++)
			esk[i] = (byte) (Math.random() * 0xFF);
	}
	//产生随机数
	public static byte [] CreateRandonAsc2Key(int mode,byte [] Pin,int len)
	{
		byte [] v_buf = null;
		Random rand = new Random();
		if(len < 0) return v_buf;
		v_buf = new byte[len];
		if(mode == 0) //由PIN码转换一组数据
		{
			for(int i = 0; i < 4; i ++)
			{
				v_buf[i * 4] = (byte) (0x30 + ((Pin[i]&0xFF) % 10));
				v_buf[i * 4 + 1] = (byte) (0x30 + (((Pin[i] >>> 2)&0xFF) % 10));
				v_buf[i * 4 + 2] = (byte) (0x30 + (((Pin[i] >>> 4)&0xFF) % 10));
				v_buf[i * 4 + 3] = (byte) (0x30 + (((Pin[i] >>> 6)&0xFF) % 10));
			}
		}
		else
		{
			v_buf[0] = (byte) (0x31 + rand.nextInt(8));
			for(int i = 1; i < len; i ++)
				v_buf[i] = (byte) (0x30 + rand.nextInt(9));
		}
		return v_buf;
	}
	//安全算法
	public static short seedToKey(byte[] pin,int level,byte[] seed,int Plen,byte[] key,int Psize)
	{
		short error = 0;
		int mask = 0;
		if(Common.Debug) Log.i(TAG,"Seed=" + Commonfunc.bytesToHexString(seed, 0, Plen));
		if (seed[1] == 0 && seed[2] == 0)
		{
			key[0] = 0x00;
			key[1] = 0x00;
			key[2] = 0x00;
			key[3] = 0x00;
		}
		else
		{
			if(level == 1) //27 01
				mask = 0x41578702;
			else	//27 03
				mask = ((pin[0]&0xFF) << 24) + ((pin[1]&0xFF) << 16) +((pin[2]&0xFF) << 8) + (pin[3]&0xFF);
			if(Common.Debug) Log.i(TAG,"mask=" + Integer.toHexString(mask));
			int  wort = ((seed[0]&0xFF) << 24) + ((seed[1]&0xFF) << 16) +((seed[2]&0xFF) << 8) + (seed[3]&0xFF);
			for (int i=0; i<40; i++)
			{
				if ((wort & 0x80000000) == 0x80000000)
				{
					wort = wort << 1;
					wort = wort ^ mask;
				}
				else
				{
					wort = wort << 1;
				}
			}
			for (int i=0; i<4; i++)
			{
				key[0] = (byte) ((wort >> 24) & 0xFF);
				key[1] = (byte) ((wort >> 16) & 0xFF);
				key[2] = (byte) ((wort >> 8) & 0xFF);
				key[3] = (byte) ((wort >> 0) & 0xFF);
			}
		}
		if(Common.Debug) Log.i(TAG,"Key=" + Commonfunc.bytesToHexString(key, 0,Psize));
		return error;
	}
	//力帆720PEPS安全算法
	public static void Peps720seedToKey(byte [] seed,byte [] key)
	{
		int i;
		int wort = 0;
		int mask = 0x4D5A16E3;
		/* The array for SEED starts with [1], the array for KEY starts with [0] */
		/* seed contains the SEED */
		/* length contains the number of bytes of seed */
		/* key contains the KEY  */
		/* retLen contains the number of bytes*/
		if (seed[1] == 0 && seed[2] == 0)
			return;
		else
		{
			wort = ((seed[0]&0xFF) << 24) + ((seed[1]&0xFF) << 16) +((seed[2]&0xFF) << 8) + (seed[3]&0xFF);
			for (i=0; i<40; i++)
			{
				if ((wort & 0x80000000) == 0x80000000)
				{
					wort = wort << 1;
					wort = wort ^ mask;
				}
				else
				{
					wort = wort << 1;
				}
			}
			for (i=0; i<4; i++)
			{
				key[i] = (byte) (wort >> (8*(3 - i)));
			}
		}
		return;
	}
	//GAOTIAN SRS安全算法
	public static boolean GaoTianSRSsafekey(byte[] seed,byte[] key)
	{
		byte [] Xor = {(byte) 0xE9,0x4A,0x22,(byte) 0x91};
		byte [] Cal = new byte[4];
		int Key = 0;
		for(int k = 0; k < 4; k ++)
			Cal[k] = (byte) (seed[k] ^ Xor[k]);
		Key = Key | (((Cal[3] & 0x0F) << 4) | (Cal[3] & 0xF0)) << 24;
		Key = Key | (((Cal[1] & 0x0F) << 4) | ((Cal[0] & 0xF0) >> 4)) << 16;
		Key = Key | ((Cal[1] & 0xF0) | ((Cal[2] & 0xF0) >> 4)) << 8;
		Key = Key | (((Cal[0] & 0x0F) << 4) | (Cal[2] & 0x0F));
		key[0] = (byte) ((Key >> 24) % 0xFF);
		key[1] = (byte) ((Key >> 16) & 0xFF);
		key[2] = (byte) ((Key >> 8) & 0xFF);
		key[3] = (byte) ((Key >> 0) & 0xFF);
		return true;
	}
	//高田 X60算法
	public static boolean GaoTianX60SRSsafekey(byte[] seed,byte[] key)
	{
		int k1 = 0x248699;
		int k2 = 0x2927;
		int sed = (seed[0]&0xFF) * 0x10000 + (seed[1]&0xFF) * 0x100 + (seed[2]&0xFF);
		int A = (k2 * sed) + k1;
		int B = (k2 * sed) - k1;
		int Key = A ^ B;
		key[0] = (byte) ((Key >> 16) & 0xFF);
		key[1] = (byte) ((Key >> 8) & 0xFF);
		key[2] = (byte) ((Key >> 0) & 0xFF);
		return true;
	}
	//江淮联电安全算法
	public static void Jac_UAES_Encrypt(byte [] v, byte n, byte [] k, byte [] del)
	{
		byte z = v[n-1], y = v[0], delta = del[0], sum = 0, e=0,x;

		int p=0, q=0;
		if (n < 1)
		{
			return;
		}

		q = 6 + 52 / n;
		while (q-- > 0)
		{
			sum += delta;
			e = (byte) (sum >> 2 & 3);
			for (p = 0; p < n-1; p++)
			{
				y = v[p + 1];
				x = v[p];
				x += (byte) ((((z&0xFF) >> 5) ^ ((y&0xFF) << 2)) + (((y&0xFF) >> 3) ^
						((z&0xFF) << 4)) ^ (((sum&0xFF) ^ (y&0xFF)) + ((k[(p & 3) ^ e]&0xFF) ^ (z&0xFF))));
				v[p] = (byte) x;
				z = x;
			}
			y = v[0];
			x = v[n-1];
			x += (byte) ((((z&0xFF) >> 5) ^ ((y&0xFF) << 2)) + (((y&0xFF) >> 3) ^
					((z&0xFF) << 4)) ^ (((sum&0xFF) ^ (y&0xFF)) + ((k[(p & 3) ^ e]&0xFF) ^ (z&0xFF))));
			v[n-1] = (byte) x;
			z = x;
		}
	}
	//瑞风M5算法
	public static void jac_m5_encipher(int num_ruonds,byte [] seed,byte [] key,int [] constkey)
	{
		int i = 0;
		int v0 = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v1 = ((~seed[0])&0xFF) * 0x1000000 + ((~seed[1])&0xFF) * 0x10000 + ((~seed[2])&0xFF) * 0x100 + ((~seed[3])&0xFF);
		int sum = 0,delta = 0x9e3779B9;
		for(i = 0; i < num_ruonds; i ++)
		{
			v0 += (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + constkey[sum & 3]);
			sum += delta;
			v1 += (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + constkey[(sum >>> 11) & 3]);
		}
		key[0] = (byte) ((v0 >> 24) & 0xFF);
		key[1] = (byte) ((v0 >> 16) & 0xFF);
		key[2] = (byte) ((v0 >> 8) & 0xFF);
		key[3] = (byte) ((v0 >> 0) & 0xFF);
	}
	//联电ME788 S3 A30写VIN码算法
	public static void jac_s3_uaes_vin_safekey(byte [] seed,byte [] key)
	{
		int [] constkey = new int[4];
		constkey[0] = 0xC4945515;
		constkey[1] = 0x49534545;
		constkey[2] = 0x444B4559;
		constkey[3] = 0x14C474F4;
		jac_m5_encipher(2, seed, key, constkey);
	}
	//B11A TCU uaes安全算法
	public static void zotye_b11a_tcu_uaes_safekey(byte [] seed,byte [] key)
	{
		int [] constkey = new int[4];
		constkey[0] = 0x4C495551;
		constkey[1] = 0x49534545;
		constkey[2] = 0x444B4559;
		constkey[3] = 0x414C474F;
		jac_m5_encipher(2, seed, key, constkey);
	}
	public static void jac_M4_CTI_safekey(byte [] seed,byte [] key)
	{
		int [] constkey = new int[4];
		constkey[0] = 0x5E2A4981;
		constkey[1] = 0x5E2A4603;
		constkey[2] = 0x5E2A4147;
		constkey[3] = 0x5E2A4445;
		jac_m5_encipher(2, seed, key, constkey);
	}




	//JAC德尔福MT80/MT22.1安全算法
	public static void jac_delphi_80_22_1_safekey(byte [] seed,byte [] key)
	{
		byte [] jac_samask = {0x4A,0x57,0x41,0x43};
		byte [] cal = new byte[4];
		cal[0] = (byte) (seed[0] ^ jac_samask[0]);
		cal[1] = (byte) (seed[1] ^ jac_samask[1]);
		cal[2] = (byte) (seed[2] ^ jac_samask[2]);
		cal[3] = (byte) (seed[3] ^ jac_samask[3]);
		key[0] = (byte) ((cal[2]&0x0F) | (cal[2]&0xF0));
		key[1] = (byte) (((cal[0]&0x0F)<<4) | ((cal[1]&0xF0) >> 4));
		key[2] = (byte) ((cal[1]&0xF0) | ((cal[3]&0xF0) >> 4));
		key[3] = (byte) (((cal[0]&0x0F) << 4) | (cal[3]&0x0F));
	}
	//JAC德尔福MT20U2/MT22U/MT22.1.1  only 2byte
	public static void jac_delphi_20_22_22_1_1_safekey(byte [] seed,byte [] key)
	{
		byte [] samask = {'J','A'};
		byte [] cal = new byte[2];
		byte [] v_key = new byte[2];
		short key_value = 0;
		cal[0] = (byte) (seed[0] ^ samask[0]);
		cal[1] = (byte) (seed[1] ^ samask[1]);
		v_key[0] = (byte) ((cal[0]&0x0F) | (cal[1]&0xF0));
		v_key[1] = (byte) (((cal[0&0xF0]) >> 4) | ((cal[1]&0x0F) << 4));
		key_value = (short) ((v_key[0]&0xFF) * 0x100 + (v_key[1]&0xFF));
		key_value = (short) ~key_value;
		if(key_value == 0 || key_value == 0xFFFF)
		{
			key_value = 1;
		}
		//复制到KEY
		key[0] = (byte) ((key_value >> 8) & 0xFF);
		key[1] = (byte) (key_value & 0xFF);
	}
	//JDZ BAIC BCM safekey
	public static void hongyuan_bcm_safekey(byte[] seed,byte[] key)
	{
		int learnmask = 0x5827A3B6;
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		if(v_seed != 0)
		{
			for(int i = 0; i < 35; i ++)
			{
				if((v_seed & 0x80000000) == 0x80000000)
				{
					v_seed = v_seed << 1;
					v_seed = v_seed ^ learnmask;
				}
				else
				{
					v_seed = v_seed << 1;
				}
			}
			v_key = v_seed;
		}
		//输出到key
		key[0] = (byte) ((v_key >>> 24) & 0xFF);
		key[1] = (byte) ((v_key >>> 16) & 0xFF);
		key[2] = (byte) ((v_key >>> 8) & 0xFF);
		key[3] = (byte) ((v_key >>> 0) & 0xFF);
	}
	//JDZ BAIC EMS safekey
	public static void hongyuan_ems_safekey(byte[] seed,byte[] key)
	{
		int learnmask = 0x2459D1A3;
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		if(v_seed != 0)
		{
			for(int i = 0; i < 30; i ++)
			{
				if((v_seed & 0x80000000) == 0x80000000)
				{
					v_seed = v_seed << 1;
					v_seed = v_seed ^ learnmask;
				}
				else
				{
					v_seed = v_seed << 1;
				}
			}
			v_key = v_seed;
		}
		//输出到key
		key[0] = (byte) ((v_key >>> 24) & 0xFF);
		key[1] = (byte) ((v_key >>> 16) & 0xFF);
		key[2] = (byte) ((v_key >>> 8) & 0xFF);
		key[3] = (byte) ((v_key >>> 0) & 0xFF);
	}
	public static void hongyuan_eps_safekey(byte[] seed,byte[] key)
	{
		int learnmask = 0x62514039;
		//int learnmask = 0x5827A3B6;
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		if((v_seed&0xFFFF0000) != 0)
		{
			for(int i = 0; i < 35; ++ i)
			{
				if((v_seed & 0x80000000) == 0x80000000)
				{
					v_seed = v_seed << 1;
					v_seed = v_seed ^ learnmask;
				}
				else
				{
					v_seed = v_seed << 1;
				}
			}
			v_key = v_seed;
		}
		//输出到key
		key[0] = (byte) ((v_key >>> 24) & 0xFF);
		key[1] = (byte) ((v_key >>> 16) & 0xFF);
		key[2] = (byte) ((v_key >>> 8) & 0xFF);
		key[3] = (byte) ((v_key >>> 0) & 0xFF);
	}

	//JDZ BAIC ICM safekey
	public static void hongyuan_icm_safekey(byte[] seed,byte[] key)
	{
		int learnmask = 0x25340168;
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		if(v_seed != 0)
		{
			for(int i = 0; i < 30; i ++)
			{
				if((v_seed & 0x80000000) == 0x80000000)
				{
					v_seed = v_seed << 1;
					v_seed = v_seed ^ learnmask;
				}
				else
				{
					v_seed = v_seed << 1;
				}
			}
			v_key = v_seed;
		}
		//输出到key
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void hongyuan_ABS_safekey(byte[] seed,byte[] key)
	{
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		v_key = (((v_seed >>> 4) ^ v_seed) << 3) ^ v_seed;
		//输出到key
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void CHAOHU_ABS_safekey(byte[] seed,byte[] key)
	{
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		v_key = (((v_seed >> 2) ^ v_seed) << 3) ^ v_seed;
		//输出到key
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void hongyuan_ACU_safekey(byte[] seed,byte[] key)
	{
		int constkey = 0x26031961;
		int v_seed = (seed[0]&0xFF) * 0x100 + (seed[1]&0xFF);
		v_seed = (v_seed >>> 5) | (v_seed << 23);
		v_seed *= 7;
		v_seed ^= constkey;
		//输出到key
		key[0] = (byte) ((v_seed >> 8) & 0xFF);
		key[1] = (byte) ((v_seed >> 0) & 0xFF);
	}
	public static void hongyuan_HUM_safekey(byte[] seed,byte[] key)
	{
		int [][] SS = { {
				0x2989, 0x0585, 0x16c6, 0x13c3, 0x1444, 0x1d0d, 0x2c8c, 0x2505,
				0x1d4d, 0x0343, 0x1808, 0x1e0e, 0x1141, 0x3ccc, 0x0aca, 0x2343,
				0x2808, 0x0444, 0x2000, 0x1d8d, 0x20c0, 0x22c2, 0x08c8, 0x1707,
				0x2585, 0x0f8f, 0x0303, 0x3b4b, 0x3b8b, 0x1303, 0x12c2, 0x2ece,
				0x3040, 0x0c8c, 0x3f0f, 0x2888, 0x3202, 0x1dcd, 0x36c6, 0x3444,
				0x2ccc, 0x1585, 0x0b0b, 0x1747, 0x1c4c, 0x1b4b, 0x3d8d, 0x0101,
				0x2404, 0x1c0c, 0x3343, 0x1888, 0x1000, 0x0ccc, 0x32c2, 0x19c9,
				0x2c0c, 0x27c7, 0x3242, 0x0383, 0x1b8b, 0x11c1, 0x0686, 0x09c9,
				0x2040, 0x1040, 0x2383, 0x2bcb, 0x0d0d, 0x3686, 0x1e8e, 0x0f4f,
				0x3787, 0x1a4a, 0x06c6, 0x3848, 0x2686, 0x1202, 0x2f8f, 0x15c5,
				0x2141, 0x03c3, 0x3484, 0x0141, 0x1242, 0x3d4d, 0x0d8d, 0x0808,
				0x1f0f, 0x1989, 0x0000, 0x1909, 0x0404, 0x1343, 0x37c7, 0x21c1,
				0x3dcd, 0x3646, 0x2f0f, 0x2707, 0x3080, 0x0b8b, 0x0e0e, 0x2b8b,
				0x2282, 0x2e4e, 0x1383, 0x0d4d, 0x2949, 0x3c4c, 0x0909, 0x0a0a,
				0x3f8f, 0x2fcf, 0x33c3, 0x05c5, 0x0787, 0x1404, 0x3ece, 0x2444,
				0x1ece, 0x2e0e, 0x0b4b, 0x1a0a, 0x0606, 0x2101, 0x2b4b, 0x2646,
				0x0202, 0x35c5, 0x1282, 0x0a8a, 0x0c0c, 0x3383, 0x3e4e, 0x10c0,
				0x3a4a, 0x0747, 0x1686, 0x25c5, 0x2606, 0x0080, 0x2d8d, 0x1fcf,
				0x2181, 0x3000, 0x3707, 0x2e8e, 0x3606, 0x1505, 0x2202, 0x3808,
				0x34c4, 0x2787, 0x0545, 0x0c4c, 0x0181, 0x29c9, 0x0484, 0x1787,
				0x3505, 0x0bcb, 0x0ece, 0x3c0c, 0x3141, 0x1101, 0x07c7, 0x0989,
				0x3545, 0x3bcb, 0x1aca, 0x38c8, 0x1484, 0x1949, 0x0282, 0x04c4,
				0x3fcf, 0x0949, 0x3909, 0x2747, 0x00c0, 0x0fcf, 0x17c7, 0x3888,
				0x0f0f, 0x0e8e, 0x0242, 0x2303, 0x1181, 0x2c4c, 0x1bcb, 0x2484,
				0x3404, 0x31c1, 0x0848, 0x02c2, 0x2f4f, 0x3d0d, 0x2d0d, 0x0040,
				0x3e8e, 0x3e0e, 0x3c8c, 0x01c1, 0x2a8a, 0x3a8a, 0x0e4e, 0x1545,
				0x3b0b, 0x1ccc, 0x2848, 0x3f4f, 0x1c8c, 0x18c8, 0x0a4a, 0x1646,
				0x3747, 0x2080, 0x2dcd, 0x0646, 0x3585, 0x2b0b, 0x2545, 0x3aca,
				0x23c3, 0x3989, 0x3181, 0x1f8f, 0x1e4e, 0x39c9, 0x26c6, 0x3282,
				0x3101, 0x2aca, 0x2d4d, 0x1f4f, 0x24c4, 0x30c0, 0x0dcd, 0x0888,
				0x1606, 0x3a0a, 0x1848, 0x14c4, 0x2242, 0x2909, 0x0707, 0x3303,
				0x28c8, 0x1b0b, 0x0505, 0x3949, 0x1080, 0x2a4a, 0x2a0a, 0x1a8a
		}, {
				0x3838, 0xe828, 0x2c2d, 0xa426, 0xcc0f, 0xdc1e, 0xb033, 0xb838,
				0xac2f, 0x6020, 0x5415, 0xc407, 0x4404, 0x6c2f, 0x682b, 0x581b,
				0xc003, 0x6022, 0x3033, 0xb435, 0x2829, 0xa020, 0xe022, 0xa427,
				0xd013, 0x9011, 0x1011, 0x0406, 0x1c1c, 0xbc3c, 0x3436, 0x480b,
				0xec2f, 0x8808, 0x6c2c, 0xa828, 0x1417, 0xc404, 0x1416, 0xf434,
				0xc002, 0x4405, 0xe021, 0xd416, 0x3c3f, 0x3c3d, 0x8c0e, 0x9818,
				0x2828, 0x4c0e, 0xf436, 0x3c3e, 0xa425, 0xf839, 0x0c0d, 0xdc1f,
				0xd818, 0x282b, 0x6426, 0x783a, 0x2427, 0x2c2f, 0xf031, 0x7032,
				0x4002, 0xd414, 0x4001, 0xc000, 0x7033, 0x6427, 0xac2c, 0x880b,
				0xf437, 0xac2d, 0x8000, 0x1c1f, 0xc80a, 0x2c2c, 0xa82a, 0x3434,
				0xd012, 0x080b, 0xec2e, 0xe829, 0x5c1d, 0x9414, 0x1818, 0xf838,
				0x5417, 0xac2e, 0x0808, 0xc405, 0x1013, 0xcc0d, 0x8406, 0xb839,
				0xfc3f, 0x7c3d, 0xc001, 0x3031, 0xf435, 0x880a, 0x682a, 0xb031,
				0xd011, 0x2020, 0xd417, 0x0002, 0x2022, 0x0404, 0x6828, 0x7031,
				0x0407, 0xd81b, 0x9c1d, 0x9819, 0x6021, 0xbc3e, 0xe426, 0x5819,
				0xdc1d, 0x5011, 0x9010, 0xdc1c, 0x981a, 0xa023, 0xa82b, 0xd010,
				0x8001, 0x0c0f, 0x4407, 0x181a, 0xe023, 0xec2c, 0x8c0d, 0xbc3f,
				0x9416, 0x783b, 0x5c1c, 0xa022, 0xa021, 0x6023, 0x2023, 0x4c0d,
				0xc808, 0x9c1e, 0x9c1c, 0x383a, 0x0c0c, 0x2c2e, 0xb83a, 0x6c2e,
				0x9c1f, 0x581a, 0xf032, 0x9012, 0xf033, 0x4809, 0x7838, 0xcc0c,
				0x1415, 0xf83b, 0x7030, 0x7435, 0x7c3f, 0x3435, 0x1010, 0x0003,
				0x6424, 0x6c2d, 0xc406, 0x7434, 0xd415, 0xb434, 0xe82a, 0x0809,
				0x7436, 0x1819, 0xfc3e, 0x4000, 0x1012, 0xe020, 0xbc3d, 0x0405,
				0xf83a, 0x0001, 0xf030, 0x282a, 0x5c1e, 0xa829, 0x5416, 0x4003,
				0x8405, 0x1414, 0x8809, 0x981b, 0xb030, 0xe425, 0x4808, 0x7839,
				0x9417, 0xfc3c, 0x1c1e, 0x8002, 0x2021, 0x8c0c, 0x181b, 0x5c1f,
				0x7437, 0x5414, 0xb032, 0x1c1d, 0x2425, 0x4c0f, 0x0000, 0x4406,
				0xec2d, 0x5818, 0x5012, 0xe82b, 0x7c3e, 0xd81a, 0xc809, 0xfc3d,
				0x3030, 0x9415, 0x6425, 0x3c3c, 0xb436, 0xe424, 0xb83b, 0x7c3c,
				0x0c0e, 0x5010, 0x3839, 0x2426, 0x3032, 0x8404, 0x6829, 0x9013,
				0x3437, 0xe427, 0x2424, 0xa424, 0xc80b, 0x5013, 0x080a, 0x8407,
				0xd819, 0x4c0c, 0x8003, 0x8c0f, 0xcc0e, 0x383b, 0x480a, 0xb437
		}, {
				0xa1a8, 0x8184, 0xd2d4, 0xd3d0, 0x5054, 0x111c, 0xa0ac, 0x2124,
				0x515c, 0x4340, 0x1018, 0x121c, 0x5150, 0xf0fc, 0xc2c8, 0x6360,
				0x2028, 0x4044, 0x2020, 0x919c, 0xe0e0, 0xe2e0, 0xc0c8, 0x1314,
				0xa1a4, 0x838c, 0x0300, 0x7378, 0xb3b8, 0x1310, 0xd2d0, 0xe2ec,
				0x7070, 0x808c, 0x333c, 0xa0a8, 0x3230, 0xd1dc, 0xf2f4, 0x7074,
				0xe0ec, 0x9194, 0x0308, 0x5354, 0x505c, 0x5358, 0xb1bc, 0x0100,
				0x2024, 0x101c, 0x7370, 0x9098, 0x1010, 0xc0cc, 0xf2f0, 0xd1d8,
				0x202c, 0xe3e4, 0x7270, 0x8380, 0x9398, 0xd1d0, 0x8284, 0xc1c8,
				0x6060, 0x5050, 0xa3a0, 0xe3e8, 0x010c, 0xb2b4, 0x929c, 0x434c,
				0xb3b4, 0x5258, 0xc2c4, 0x7078, 0xa2a4, 0x1210, 0xa3ac, 0xd1d4,
				0x6160, 0xc3c0, 0xb0b4, 0x4140, 0x5250, 0x717c, 0x818c, 0x0008,
				0x131c, 0x9198, 0x0000, 0x1118, 0x0004, 0x5350, 0xf3f4, 0xe1e0,
				0xf1fc, 0x7274, 0x232c, 0x2324, 0xb0b0, 0x8388, 0x020c, 0xa3a8,
				0xa2a0, 0x626c, 0x9390, 0x414c, 0x6168, 0x707c, 0x0108, 0x0208,
				0xb3bc, 0xe3ec, 0xf3f0, 0xc1c4, 0x8384, 0x1014, 0xf2fc, 0x6064,
				0xd2dc, 0x222c, 0x4348, 0x1218, 0x0204, 0x2120, 0x6368, 0x6264,
				0x0200, 0xf1f4, 0x9290, 0x8288, 0x000c, 0xb3b0, 0x727c, 0xd0d0,
				0x7278, 0x4344, 0x9294, 0xe1e4, 0x2224, 0x8080, 0xa1ac, 0xd3dc,
				0xa1a0, 0x3030, 0x3334, 0xa2ac, 0x3234, 0x1114, 0x2220, 0x3038,
				0xf0f4, 0xa3a4, 0x4144, 0x404c, 0x8180, 0xe1e8, 0x8084, 0x9394,
				0x3134, 0xc3c8, 0xc2cc, 0x303c, 0x7170, 0x1110, 0xc3c4, 0x8188,
				0x7174, 0xf3f8, 0xd2d8, 0xf0f8, 0x9094, 0x5158, 0x8280, 0xc0c4,
				0xf3fc, 0x4148, 0x3138, 0x6364, 0xc0c0, 0xc3cc, 0xd3d4, 0xb0b8,
				0x030c, 0x828c, 0x4240, 0x2320, 0x9190, 0x606c, 0xd3d8, 0xa0a4,
				0x3034, 0xf1f0, 0x4048, 0xc2c0, 0x636c, 0x313c, 0x212c, 0x4040,
				0xb2bc, 0x323c, 0xb0bc, 0xc1c0, 0xa2a8, 0xb2b8, 0x424c, 0x5154,
				0x3338, 0xd0dc, 0x6068, 0x737c, 0x909c, 0xd0d8, 0x4248, 0x5254,
				0x7374, 0xa0a0, 0xe1ec, 0x4244, 0xb1b4, 0x2328, 0x6164, 0xf2f8,
				0xe3e0, 0xb1b8, 0xb1b0, 0x939c, 0x525c, 0xf1f8, 0xe2e4, 0xb2b0,
				0x3130, 0xe2e8, 0x616c, 0x535c, 0xe0e4, 0xf0f0, 0xc1cc, 0x8088,
				0x1214, 0x3238, 0x5058, 0xd0d4, 0x6260, 0x2128, 0x0304, 0x3330,
				0xe0e8, 0x1318, 0x0104, 0x7178, 0x9090, 0x6268, 0x2228, 0x9298
		}, {
				0x0830, 0xc8e0, 0x0d21, 0x86a2, 0xcfc3, 0xced2, 0x83b3, 0x88b0,
				0x8fa3, 0x4060, 0x4551, 0xc7c3, 0x4440, 0x4f63, 0x4b63, 0x4b53,
				0xc3c3, 0x4262, 0x0333, 0x85b1, 0x0921, 0x80a0, 0xc2e2, 0x87a3,
				0xc3d3, 0x8191, 0x0111, 0x0602, 0x0c10, 0x8cb0, 0x0632, 0x4b43,
				0xcfe3, 0x8880, 0x4c60, 0x88a0, 0x0713, 0xc4c0, 0x0612, 0xc4f0,
				0xc2c2, 0x4541, 0xc1e1, 0xc6d2, 0x0f33, 0x0d31, 0x8e82, 0x8890,
				0x0820, 0x4e42, 0xc6f2, 0x0e32, 0x85a1, 0xc9f1, 0x0d01, 0xcfd3,
				0xc8d0, 0x0b23, 0x4662, 0x4a72, 0x0723, 0x0f23, 0xc1f1, 0x4272,
				0x4242, 0xc4d0, 0x4141, 0xc0c0, 0x4373, 0x4763, 0x8ca0, 0x8b83,
				0xc7f3, 0x8da1, 0x8080, 0x0f13, 0xcac2, 0x0c20, 0x8aa2, 0x0430,
				0xc2d2, 0x0b03, 0xcee2, 0xc9e1, 0x4d51, 0x8490, 0x0810, 0xc8f0,
				0x4753, 0x8ea2, 0x0800, 0xc5c1, 0x0313, 0xcdc1, 0x8682, 0x89b1,
				0xcff3, 0x4d71, 0xc1c1, 0x0131, 0xc5f1, 0x8a82, 0x4a62, 0x81b1,
				0xc1d1, 0x0020, 0xc7d3, 0x0202, 0x0222, 0x0400, 0x4860, 0x4171,
				0x0703, 0xcbd3, 0x8d91, 0x8991, 0x4161, 0x8eb2, 0xc6e2, 0x4951,
				0xcdd1, 0x4151, 0x8090, 0xccd0, 0x8a92, 0x83a3, 0x8ba3, 0xc0d0,
				0x8181, 0x0f03, 0x4743, 0x0a12, 0xc3e3, 0xcce0, 0x8d81, 0x8fb3,
				0x8692, 0x4b73, 0x4c50, 0x82a2, 0x81a1, 0x4363, 0x0323, 0x4d41,
				0xc8c0, 0x8e92, 0x8c90, 0x0a32, 0x0c00, 0x0e22, 0x8ab2, 0x4e62,
				0x8f93, 0x4a52, 0xc2f2, 0x8292, 0xc3f3, 0x4941, 0x4870, 0xccc0,
				0x0511, 0xcbf3, 0x4070, 0x4571, 0x4f73, 0x0531, 0x0010, 0x0303,
				0x4460, 0x4d61, 0xc6c2, 0x4470, 0xc5d1, 0x84b0, 0xcae2, 0x0901,
				0x4672, 0x0911, 0xcef2, 0x4040, 0x0212, 0xc0e0, 0x8db1, 0x0501,
				0xcaf2, 0x0101, 0xc0f0, 0x0a22, 0x4e52, 0x89a1, 0x4652, 0x4343,
				0x8581, 0x0410, 0x8981, 0x8b93, 0x80b0, 0xc5e1, 0x4840, 0x4971,
				0x8793, 0xccf0, 0x0e12, 0x8282, 0x0121, 0x8c80, 0x0b13, 0x4f53,
				0x4773, 0x4450, 0x82b2, 0x0d11, 0x0521, 0x4f43, 0x0000, 0x4642,
				0xcde1, 0x4850, 0x4252, 0xcbe3, 0x4e72, 0xcad2, 0xc9c1, 0xcdf1,
				0x0030, 0x8591, 0x4561, 0x0c30, 0x86b2, 0xc4e0, 0x8bb3, 0x4c70,
				0x0e02, 0x4050, 0x0931, 0x0622, 0x0232, 0x8480, 0x4961, 0x8393,
				0x0733, 0xc7e3, 0x0420, 0x84a0, 0xcbc3, 0x4353, 0x0a02, 0x8783,
				0xc9d1, 0x4c40, 0x8383, 0x8f83, 0xcec2, 0x0b33, 0x4a42, 0x87b3
		} };

		int v_seed = (seed[0]&0xFF) * 0x100 + (seed[1]&0xFF);
		int tempkeyX = v_seed % 4;
		int tempkeyY = (seed[0] ^ seed[1])&0xFF;
		//输出到key
		key[0] = (byte) ((SS[tempkeyX][tempkeyY] >> 8) & 0xFF);
		key[1] = (byte) ((SS[tempkeyX][tempkeyY] >> 0) & 0xFF);
	}
	public static void hongyuan_TCU_safekey(byte[] seed,byte[] key)
	{
		hongyuan_tcu_calc(seed,key);
		byte [] v_seed = new byte[2];
		byte [] v_key = new byte[2];
		v_seed[0] = seed[2];
		v_seed[1] = seed[3];
		hongyuan_tcu_calc(v_seed,v_key);
		//输出到key
		key[2] = v_key[0];
		key[3] = v_key[1];
	}
	private static void hongyuan_tcu_calc(byte[] seed,byte[] key)
	{
		byte seedH,seedL;
		seedH = seed[0];
		seedL = seed[1];
		seedH = (byte) (((seedH&0xFF) >>> 3) | ((seedH&0xFF) << 5));
		seedL = (byte) (((seedL&0xFF) >>> 3) | ((seedL&0xFF) << 5));

		seedH = (byte) (((seedH&0xAA) >>> 1) | ((seedH&0x55) << 1));
		seedL = (byte) (((seedL&0xAA) >>> 1) | ((seedL&0x55) << 1));

		seedH = (byte) (((seedH&0xFF) << 3)| ((seedL&0xFF) >>> 5));
		seedL = (byte) (((seedL&0xFF) << 3)| ((seedH&0xFF) >>> 5));

		byte Codf1 = (byte) 0xED;
		byte Codf2 = (byte) 0xCA;

		seedH ^= Codf1;
		seedL ^= Codf2;
		key[0] = seedH;
		key[1] = seedL;
	}
	public static void hongyuan_CreatePin(byte[] vin,byte[] pin)
	{
		pin[0] = (byte) (((hongyuan_GetVinCode(vin[0]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[16])) % 16) * 0x10 +
				((hongyuan_GetVinCode(vin[1]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[15])) % 16));
		pin[1] = (byte) (((hongyuan_GetVinCode(vin[2]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[14])) % 16) * 0x10 +
				((hongyuan_GetVinCode(vin[3]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[13])) % 16));
		pin[2] = (byte) (((hongyuan_GetVinCode(vin[4]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[12])) % 16) * 0x10 +
				((hongyuan_GetVinCode(vin[5]) + hongyuan_GetVinCode(vin[8]) + hongyuan_GetVinCode(vin[11])) % 16));
		//pin[3] = (byte) (((hongyuan_GetVinCode(vin[6]) + hongyuan_GetVinCode(vin[8])) % 16) * 0x10 +
		//		((hongyuan_GetVinCode(vin[7]) + hongyuan_GetVinCode(vin[8])) % 16));
	}
	public static void hongyuan_CreateESK(byte[] vin,byte[] esk)
	{
		byte [] bcSN = new byte[10];
		bcSN[0] = 'F';
		bcSN[1] = '1';
		bcSN[2] = 'A';
		int SN = (bcSN[0] + bcSN[1] + bcSN[2]) % 0x100;
		for(int j = 0; j < 16; j ++)
		{
			if(j < 9)
				esk[j] = (byte) ((hongyuan_GetVinCode(vin[j]) + SN + hongyuan_GetVinCode(vin[9])) % 0x100);
			else
				esk[j] = (byte) ((hongyuan_GetVinCode(vin[j+1]) + SN + hongyuan_GetVinCode(vin[9])) % 0x100);
		}
	}
	private static int hongyuan_GetVinCode(byte P)
	{
		int value = 0;
		if(P >= '0' && P <= '9')
			value = P - 0x30;
		else if(P >= 'A' && P <= 'H')
			value = P - 'A' + 10;
		else if(P >= 'J' && P <= 'N')
			value = P - 'J' + 18;
		else if(P =='P')
			value = 23;
		else if(P >= 'R' && P <= 'Z')
			value = P - 'R' + 24;
		else
			return 0;
		return value;
	}
	public static void hongyuan_SDM_safekey(byte[] seed,byte[] key)
	{
		int TOPBIT = 0x8000;
		int POLYNOM_1 = 0x4632;
		int POLYNOM_2 = 0x8752;
		int BITMASK = 0x0080;
		int INITIAL_REMINDER = 0xFFFE;
		int MSG_LEN = 2; /* seed length in bytes */
		byte [] bSeed = new byte[2];
		short remainder;
		byte n;
		byte i;
		bSeed[0] = seed[0]; /* MSB */
		bSeed[1] = seed[1]; /* LSB */
		remainder = (short) INITIAL_REMINDER;
		for (n = 0; n < MSG_LEN; n++)
		{
			/* Bring the next byte into the remainder. */
			remainder ^= ((bSeed[n]) << 8);

			/* Perform modulo-2 division, a bit at a time. */
			for (i = 0; i < 8; i++)
			{
				/* Try to divide the current data bit. */
				if ((remainder & TOPBIT) != 0)
				{
					if((remainder & BITMASK) != 0)
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_1);
					}
					else
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_2);
					}
				}
				else
				{
					remainder = (short) (remainder << 1);
				}
			}
		}
		key[0] = (byte) ((remainder >>> 8)&0xFF);
		key[1] = (byte) (remainder & 0xFF);
	}
	//合肥chery bcm
	public static void hefei_BCM_safekey(byte[] seed,byte[] key)
	{
		int TOPBIT = 0x8000;
		int POLYNOM_1 = 0x8408;
		int POLYNOM_2 = 0x8025;
		int BITMASK = 0x0080;
		int INITIAL_REMINDER = 0xFFFE;
		int MSG_LEN = 2; /* seed length in bytes */
		byte [] bSeed = new byte[2];
		short remainder;
		byte n;
		byte i;
		bSeed[0] = seed[0]; /* MSB */
		bSeed[1] = seed[1]; /* LSB */
		remainder = (short) INITIAL_REMINDER;
		for (n = 0; n < MSG_LEN; n++)
		{
			/* Bring the next byte into the remainder. */
			remainder ^= ((bSeed[n]) << 8);

			/* Perform modulo-2 division, a bit at a time. */
			for (i = 0; i < 8; i++)
			{
				/* Try to divide the current data bit. */
				if ((remainder & TOPBIT) != 0)
				{
					if((remainder & BITMASK) != 0)
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_1);
					}
					else
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_2);
					}
				}
				else
				{
					remainder = (short) (remainder << 1);
				}
			}
		}
		key[0] = (byte) ((remainder >>> 8)&0xFF);
		key[1] = (byte) (remainder & 0xFF);
	}
	//ZOTYE金坛项目算法汇总
	public static void Zotye_Greate_PinAndEsk(String vin,byte[] Pincode,byte[] EskCode)
	{
		DesVinToPin desvin = new DesVinToPin();
		desvin.GererateZotyePin(vin, Pincode);
		for(int i = 0; i < 4; i ++)
			System.arraycopy(Pincode, 0, EskCode, 4 * i, 4);
	}
	//B11 ICU
	public static void Zotye_icu_Encrypt(byte[] seed,int len,byte [] key)
	{
		byte [] xor = {0x14,0x11,0x75,(byte) 0xC2,0x62,(byte) 0xB3,(byte) 0xD2,0x56};
		byte [] cal = new byte[8];
		for(int i = 0; i < 4; i ++)
			cal[i] = (byte) (seed[i]^xor[i]);
		for(int i = 4; i < 8; i ++)
			cal[i] = (byte) (seed[i - 4] ^ xor[i]);
		for(int i = 0; i < 4; i ++)
			key[i] = (byte) (cal[i] + cal[i + 4]);
	}
	//B11 SRS
	public static void Zotye_srs_Encrypt(byte[] seed,int len,byte[] key)
	{
		int v_seed = seed[0] * 0x1000000 + seed[1] * 0x10000 + seed[2] * 0x100 + seed[3];
		int v_key = 0;
		int mult = 0x55555555;
		int sum = 0x24924925;
		v_key = mult * v_seed + sum;
		if(v_seed == 0) v_key = 0;
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	//纳恩防盗算法
	public static void Zotye_NaEnPEPSSafeKey(byte[] seed,byte[] key,int MASK)
	{
		int v_key = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		if (v_seed != 0)
		{
			for (int i=0; i < 35; i++ )
			{
				if((v_seed & 0x80000000) != 0)
				{
					v_seed = v_seed << 1;
					v_seed = v_seed ^ MASK;
				}
				else
				{
					v_seed = v_seed << 1;
				}
			}
			v_key = v_seed & 0xFFFFFFFF;
		}
		key[0] = (byte) ((v_key >>> 24) & 0xFF);
		key[1] = (byte) ((v_key >>> 16) & 0xFF);
		key[2] = (byte) ((v_key >>> 8) & 0xFF);
		key[3] = (byte) ((v_key >>> 0) & 0xFF);
	}
	//B11 TCU算法
	public static void Zotye_TCU_Safekey(byte[] seed,byte[] key)
	{
		long v0 = (seed[0] & 0xFF) * 0x1000000 + (seed[1] & 0xFF) * 0x10000 + (seed[2] & 0xFF) * 0x100 + (seed[3] & 0xFF);
		long v1 = (~seed[0] & 0xFF) * 0x1000000 + (~seed[1] & 0xFF) * 0x10000 + (~seed[2] & 0xFF) * 0x100 + (~seed[3] & 0xFF);
		long sum = 0;
		long delta = 0x9E3779B9;
		long [] k = {0,0,0,0};
		k[0] =  0x4C495551;
		k[1] =  0x49534545;
		k[2] =  0x444B4559;
		k[3] =  0x414C474F;
		for(int i = 0; i < 2; i ++)
		{
			v0 +=  (((v1 << 4) ^ ((v1 >> 5)& 0x07FFFFFF)) + v1) ^ (sum + k[(int) (sum & 3)]);
			sum += delta;
			v1 +=  (((v0 << 4) ^ ((v0 >> 5)& 0x07FFFFFF)) + v0) ^ (sum + k[(int) ((sum>>11) & 3)]);
		}
		key[0] = (byte) ((v0 >>> 24) & 0xFF);
		key[1] = (byte) ((v0 >>> 16) & 0xFF);
		key[2] = (byte) ((v0 >>> 8) & 0xFF);
		key[3] = (byte) ((v0 >>> 0) & 0xFF);
	}

	//B11 TPMS算法
	public static void Zotye_tpms_calckey(byte[] seed,byte[] key)
	{
		key[0] = (byte) ((~seed[0])<<1);
		key[1] = (byte) ((~seed[1])<<1);
	}
	public static void Zotye_bcm_calcKey(byte[] seed,byte[] key)
	{
		int TOPBIT = 0x8000;
		int POLYNOM_1 = 0x8408;
		int POLYNOM_2 = 0x8025;
		int BITMASK	= 0x0080;
		int INITIAL_REMINDER = 0xFFFE;
		int MSG_LEN = 2; /* seed length in bytes */
		byte [] bSeed = new byte[2];
		int remainder;
		byte n;
		byte i;
		bSeed[0] = seed[0]; /* MSB */
		bSeed[1] = seed[1]; /* LSB */
		remainder = INITIAL_REMINDER;
		for (n = 0; n < MSG_LEN; n++)
		{
			/* Bring the next byte into the remainder. */
			remainder ^= ((bSeed[n]) << 8);
			/* Perform modulo-2 division, a bit at a time. */
			for (i = 0; i < 8; i++)
			{
				/* Try to divide the current data bit. */
				if ((remainder & TOPBIT) > 0)
				{
					if((remainder & BITMASK) > 0)
					{
						remainder = (remainder << 1) ^ POLYNOM_1;
					}
					else
					{
						remainder = (remainder << 1) ^ POLYNOM_2;
					}
				}
				else
				{
					remainder = (remainder << 1);
				}
			}
		}
		/* The final remainder is the key */
		key[0] = (byte) ((remainder >> 8) & 0xFF);
		key[1] = (byte) (remainder & 0xFF);
	}
	public static void Zotye_T22_icm_Safekey(byte[] seed,byte[] key)
	{
		byte[] Xor = {0x14,0x11,0x75,(byte) 0xC2,0x62,(byte) 0xB3,(byte) 0xD2,0x56};
		byte[] cal = new byte[8];
		for(int i= 0;i < 4;i++)
		{
			cal[i] = (byte) (seed[i] ^ Xor[i]);
		}
		for(int i= 4;i < 8;i++)
		{
			cal[i] = (byte) (seed[i-4] ^ Xor[i]);
		}
		for(int i= 0;i < 4;i++)
		{
			key[i] = (byte) (cal[i] + cal[i + 4]);
		}
	}
	public static void Zotye_B11A_icm_Safekey(byte[] seed,byte[] key)
	{
		byte[] Xor = {0x14,0x11,0x75,(byte) 0xC2,0x62,(byte) 0xB3,(byte) 0xD2,0x56};
		byte[] cal = new byte[8];
		for(int i= 0;i < 4;i++)
		{
			cal[i] = (byte) (seed[i] ^ Xor[i]);
		}
		for(int i= 4;i < 8;i++)
		{
			cal[i] = (byte) (seed[i-4] ^ Xor[i]);
		}
		for(int i= 0;i < 4;i++)
		{
			key[i] = (byte) (cal[i] + cal[i + 4]);
		}
	}
	//UAES ME1788
	public static void Zotye_T22_uaes_safekey(byte [] seed,byte [] key)
	{
		int [] constkey = new int[4];
		constkey[0] = 0x4C495551;
		constkey[1] = 0x49534545;
		constkey[2] = 0x444B4559;
		constkey[3] = 0x414C474F;
		jac_m5_encipher(2, seed, key, constkey);
	}
	//delphi
	public static void Zotye_B11A_Delphi_Safekey(byte [] seed, byte [] key)
	{
		byte [] cal = new byte[4];
		cal[0] = (byte) (seed[0] ^ 0xAF);
		cal[1] = (byte) (seed[1] ^ 0x9E);
		cal[2] = (byte) (seed[2] ^ 0x01);
		cal[3] = (byte) (seed[3] ^ 0x66);
		key[0] = (byte) ((cal[2]&0x0F) | (cal[2]&0xF0));
		key[1] = (byte) (((cal[0]&0x0F) <<4) | ((cal[1]&0xF0)>> 4));
		key[2] = (byte) ((cal[1]&0xF0) | ((cal[3]&0xF0) >> 4));
		key[3] = (byte) (((cal[0]&0x0F) << 4) | (cal[3]&0x0F));
	}
	public static void Zotye_T22_TCU_GenerateKey(byte[] seed, byte[] key)
	{
		int   project_code;
		int   temp_value;
		int   seed_r;
		int   key_r;
		int PROJECT_ZORRO = 0x5A4F;  //A02
		int PROJECT_ZEBRA = 0x5A45;	//T22
		int SEED_MULT = 0x449C;
		seed_r = (seed[0]&0xFF) * 0x100 + (seed[1]&0xFF);

		/* Calculate the key out of the stored SEED
		 * Step 1: Multiply the SEED with a security-code
		 * Step 2: XOR the key with a project identifier.
		 *       The project identifier is retrieved out of Release information,
		 *       and scrambled
		 * */
		project_code = 0;
		temp_value = 0;

		temp_value = PROJECT_ZEBRA;
		project_code =   (temp_value << 1) & 0xFE;
		project_code |= ((temp_value >> 7) & 0x1);

		project_code |= ((temp_value >> 1) & 0x7F00);
		project_code |= ((temp_value << 7) & 0x8000);

		key_r = (seed_r  * SEED_MULT) ^ project_code;
		key[0] = (byte)((key_r >> 8)&0xFF);
		key[1] = (byte)(key_r & 0xFF);
	}
	public static void Zotye_T22_SRS_Safekey(byte[] seed,byte[] key)
	{
		int MULT_CONST = 0x55555555;
		int SUM_CONST = 0x24924925;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = MULT_CONST * v_seed + SUM_CONST;
		if(v_seed == 0) v_key = 0;
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	//TBOX
	public static void Zotye_T22_ABS_Safekey(byte[] seed,byte[] key)
	{
		int unlockkey = 0;
		int unlockseed = 0;
		int undefineseed = 0xFFFFFFFF;
		int seedmask = 0x80000000;
		int shiftbit = 1;
		//int algorithmask = 0x42313131; //B11
		int algorithmask = 0x54323231; //T22
		byte u1;
		int u2;
		long u4;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = 0;
		int i = 0;

		v_key = unlockkey;
		if(!((v_seed == undefineseed) || (v_seed == unlockseed)))
		{
			for(i = 0; i < 35; i ++)
			{
				if((v_seed & seedmask) != 0)
				{
					v_seed = v_seed << shiftbit;
					v_seed = v_seed ^ algorithmask;
				}
				else
				{
					v_seed = v_seed << shiftbit;
				}
			}
			v_key = v_seed;
		}
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void Zotye_B11_Zotye_Safekey(byte[] seed,byte[] key)
	{
		int unlockkey = 0;
		int unlockseed = 0;
		int undefineseed = 0xFFFFFFFF;
		int seedmask = 0x80000000;
		int shiftbit = 1;
		int algorithmask = 0x42313131; //B11
		//int algorithmask = 0x54323231; //T22
		byte u1;
		int u2;
		long u4;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = 0;
		int i = 0;

		v_key = unlockkey;
		if(!((v_seed == undefineseed) || (v_seed == unlockseed)))
		{
			for(i = 0; i < 35; i ++)
			{
				if((v_seed & seedmask) != 0)
				{
					v_seed = v_seed << shiftbit;
					v_seed = v_seed ^ algorithmask;
				}
				else
				{
					v_seed = v_seed << shiftbit;
				}
			}
			v_key = v_seed;
		}
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}

	public static void Zotye_B01_Stand_Safekey(byte[] seed,byte[] key)
	{
		int unlockkey = 0;
		int unlockseed = 0;
		int undefineseed = 0xFFFFFFFF;
		int seedmask = 0x80000000;
		int shiftbit = 1;
		int algorithmask = 0x42303131;
		byte u1;
		int u2;
		long u4;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = 0;
		int i = 0;

		v_key = unlockkey;
		if(!((v_seed == undefineseed) || (v_seed == unlockseed)))
		{
			for(i = 0; i < 35; i ++)
			{
				if((v_seed & seedmask) != 0)
				{
					v_seed = v_seed << shiftbit;
					v_seed = v_seed ^ algorithmask;
				}
				else
				{
					v_seed = v_seed << shiftbit;
				}
			}
			v_key = v_seed;
		}
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void Zotye_E01_ABS_Safekey(byte[] seed,byte[] key)
	{
		int unlockkey = 0;
		int unlockseed = 0;
		int undefineseed = 0xFFFFFFFF;
		int seedmask = 0x80000000;
		int shiftbit = 1;
		int algorithmask = 0x45303131;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = 0;
		int i = 0;

		v_key = unlockkey;
		if(!((v_seed == undefineseed) || (v_seed == unlockseed)))
		{
			for(i = 0; i < 35; i ++)
			{
				if((v_seed & seedmask) != 0)
				{
					v_seed = v_seed << shiftbit;
					v_seed = v_seed ^ algorithmask;
				}
				else
				{
					v_seed = v_seed << shiftbit;
				}
			}
			v_key = v_seed;
		}
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void xy_s402_uaes_safekey(byte[] seed,byte[] key)
	{
		int [] constkey = new int[4];
		constkey[0] = 0x4C495551;
		constkey[1] = 0x49534545;
		constkey[2] = 0x444B4559;
		constkey[3] = 0x414C474F;

		int i = 0;
		int v0 = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v1 = ((~seed[0])&0xFF) * 0x1000000 + ((~seed[1])&0xFF) * 0x10000 + ((~seed[2])&0xFF) * 0x100 + ((~seed[3])&0xFF);
		int sum = 0,delta = 0x9e3779B9;
		for(i = 0; i < 2; i ++)
		{
			v0 += (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + constkey[sum & 3]);
			sum += delta;
			v1 += (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + constkey[(sum >>> 11) & 3]);
		}
		key[0] = (byte) ((v0 >> 24) & 0xFF);
		key[1] = (byte) ((v0 >> 16) & 0xFF);
		key[2] = (byte) ((v0 >> 8) & 0xFF);
		key[3] = (byte) ((v0 >> 0) & 0xFF);
	}
	public static void xy_s402_createSK(byte[] Pvin,byte[] Psk)
	{
		byte[] Pin = new byte[8];
		DesVinToPin v2p = new DesVinToPin();
		v2p.CreateHCXYPin(new String(Pvin),Pin);
		String v_sk = Commonfunc.bytesToHexString(Pin, 0, 4);
		v_sk += v_sk;
		Psk = v_sk.getBytes();
	}
	public static void xy_y101_peps_safekey(byte[] seed,byte[] key)
	{
		int SECURITYCONSTANT= 0x26031961;

		int v_seed = (seed[0]&0xFF) * 0x100 + (seed[1]&0xFF);
		int wLastSeed ;
		short wLastKey;
		wLastSeed= v_seed;
		wLastSeed = (wLastSeed >>> 5) | (wLastSeed<<23);
		wLastSeed *= 7;
		wLastSeed ^= SECURITYCONSTANT;
		wLastKey = (short)wLastSeed;
		key[0] = (byte) ((wLastKey >>> 8) & 0xFF);
		key[1] = (byte) ((wLastKey >>> 0) & 0xFF);
	}
	public static void xy_s402_icm_safekey(byte[] seed,byte[] key)
	{
		int  SECURITYCONSTANT= 0x26031961;
		int wLastSeed = (seed[0]&0xFF) * 0x100 + (seed[1]&0xFF); /*2 byte wSeed as LSB, and  “0x0000”  as MSB*/
		short wLastKey;
		wLastSeed = (wLastSeed>>>5) | (wLastSeed<<23);
		wLastSeed *= 7;
		wLastSeed ^= SECURITYCONSTANT;
		wLastKey = (short)wLastSeed;
		key[0] = (byte) ((wLastKey >> 8) & 0xFF);
		key[1] = (byte) ((wLastKey >> 0) & 0xFF);
	}
	public static void xy_s402_eps_old_safekey(byte[] seed,byte[] key)
	{
		int mask  = 0x969B1842;

		int i = 0;
		int v_seed = (seed[0]&0xFF) * 0x1000000 + (seed[1]&0xFF) * 0x10000 + (seed[2]&0xFF) * 0x100 + (seed[3]&0xFF);
		int v_key = 0;
		for(i = 0; i < 35; i ++)
		{
			if((v_seed & 0x80000000) != 0)
			{
				v_seed = v_seed << 1;
				v_seed = v_seed ^ mask;
			}
			else
			{
				v_seed =v_seed << 1;
			}
		}
		v_key = v_seed;
		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void xy_s402_tcu_safekey(byte[] seed,byte[] key)
	{
		long c0, c1, c2, c3;
		long v_key = 0;
		c0 = seed[0] ^ 0xE1;
		c1 = seed[1] ^ 0xD5;
		c2 = seed[2] ^ 0xC3;
		c3 = seed[3] ^ 0x03;

		v_key = (((c3 & 0x0F) << 4) | (c3 & 0xF0)) << 24;
		v_key |= (((c1 & 0x0F) << 4) | ((c0 & 0xF0) >>> 4)) << 16;
		v_key |= ((c1 & 0xF0) | ((c2 & 0xF0) >>> 4)) << 8;
		v_key |= (((c0 & 0x0F) << 4) | (c2 & 0x0F));

		key[0] = (byte) ((v_key >> 24) & 0xFF);
		key[1] = (byte) ((v_key >> 16) & 0xFF);
		key[2] = (byte) ((v_key >> 8) & 0xFF);
		key[3] = (byte) ((v_key >> 0) & 0xFF);
	}
	public static void xy_s402_tbox_Getkey(byte[] Pvin,byte[] Pkey)
	{
		char [] v_key = new char[32];
		v_key.clone();
		v_key[0]	= (char) ((Pvin[5] << 2) | (Pvin[8] >>> 4));
		v_key[1]  	= (char) ((Pvin[10] & 0x0F) | ((Pvin[8] & 0x0F) << 4));
		v_key[2]  	= (char) ((Pvin[12] << 4) | Pvin[13]);
		v_key[3]  	= (char) ((Pvin[13] ^ 0x78) | (Pvin[15] << 2));
		v_key[4]	= (char) ((Pvin[3] ^ 0xD6)  | (Pvin[10] & 0xB9));
		v_key[5]	= (char) ((Pvin[9] ^ 0xC3) | 0xA5);
		//CRC32
		int  crc = 0xFFFFFFFF;
		make_crc32_table();
		crc = make_crc(crc,Pvin,17);
		v_key[6] = (char) ((crc >> 24) & 0xFF);
		v_key[7] = (char) ((crc >> 16) & 0xFF);
		v_key[8] = (char) ((crc >> 8) & 0xFF);
		v_key[9] = (char) ((crc >> 0) & 0xFF);
		//K_Byte[0]
		Pkey[0] = 0x01;
		//K_Byte[1]
		Pkey[1] = 0x01;
		//时间
		Calendar cal;
		cal = Calendar.getInstance();
		Pkey[2] = (byte) (cal.get(Calendar.YEAR) / 100);
		Pkey[3] = (byte) (cal.get(Calendar.YEAR) % 100);
		Pkey[4] = (byte) cal.get(Calendar.MONTH);
		Pkey[5] = (byte) cal.get(Calendar.DAY_OF_MONTH);
		//复制密钥
		System.arraycopy(v_key, 0, Pkey, 6, 10);
	}
	private static int make_crc32_table()
	{
		int c;
		int i = 0;
		int bit = 0;

		for(i = 0; i < 256; i++)
		{
			c  = (int)i;

			for(bit = 0; bit < 8; bit++)
			{
				if((c&1) != 0)
				{
					c = (c >> 1)^(0xEDB88320);
				}
				else
				{
					c =  c >> 1;
				}

			}
			crc32_table[i] = c;
		}
		return 0;
	}
	private static int make_crc(int crc,byte[] string, int size)
	{
		int i = 0;
		while((size--) > 0)
		{
			crc = (crc >> 8)^(crc32_table[(crc ^ string[i++])&0xff]);
		}
		return crc;
	}
	public static void xy_S401_stand_Safekey(String Pname,byte[] Pseed,byte[] Pkey)
	{
		byte [] mask = new byte[4];
		if(Pname.equals("ICM1") || Pname.equals("IPC1"))
		{
			mask[0] = (byte) 0xE0;mask[1] = 0x59;mask[2] = (byte) 0xC3;mask[3] = 0x26;
		}
		else if(Pname.equals("AVM1"))
		{
			mask[0] = 0x7A;mask[1] = (byte) 0xE2;mask[2] = 0x63;mask[3] = 0x59;
		}
		else if(Pname.equals("CWC1"))
		{
			mask[0] = 0x08;mask[1] = (byte) 0x99;mask[2] = (byte) 0xF7;mask[3] = (byte) 0xB2;
		}
		else if(Pname.equals("EPB1"))
		{
			mask[0] = (byte) 0xC0;mask[1] = (byte) 0x81;mask[2] = 0x7D;mask[3] = 0x3F;
		}
		else if(Pname.equals("TCU1"))
		{
			mask[0] = 0x3D;mask[1] = 0x78;mask[2] = (byte) 0xF9;mask[3] = 0x73;
		}
		else if(Pname.equals("ADAS1"))
		{
			mask[0] = 0x59;mask[1] = (byte) 0xC3;mask[2] = 0x77;mask[3] = (byte) 0xB2;
		}
		else if(Pname.equals("AVCN1") || Pname.equals("AVS1"))
		{
			mask[0] = (byte) 0xE3;mask[1] = (byte) 0xA7;mask[2] = 0x59;mask[3] = 0x4A;
		}
		else if(Pname.equals("BCM1"))
		{
			mask[0] = 0x6B;mask[1] = 0x12;mask[2] = (byte) 0xD0;mask[3] = 0x38;
		}
		else if(Pname.equals("PEPS1"))
		{
			mask[0] = 0x14;mask[1] = (byte) 0x87;mask[2] = (byte) 0xAD;mask[3] = 0x5A;
		}
		else if(Pname.equals("CCU1"))
		{
			mask[0] = (byte) 0x93;mask[1] = 0x66;mask[2] = (byte) 0xE2;mask[3] = 0x01;
		}
		else if(Pname.equals("DVR1"))
		{
			mask[0] = 0x30;mask[1] = 0x24;mask[2] = 0x32;mask[3] = 0x60;
		}
		else if(Pname.equals("EMS1"))
		{
			mask[0] = 0x22;mask[1] = (byte) 0xE3;mask[2] = 0x67;mask[3] = (byte) 0x85;
		}
		else if(Pname.equals("EPS1"))
		{
			mask[0] = (byte) 0xA1;mask[1] = 0x59;mask[2] = (byte) 0xD4;mask[3] = 0x30;
		}
		else if(Pname.equals("ESC1"))
		{
			mask[0] = 0x50;mask[1] = 0x4F;mask[2] = (byte) 0x93;mask[3] = (byte) 0xC1;
		}
		else if(Pname.equals("TBOX1"))
		{
			mask[0] = (byte) 0x92;mask[1] = (byte) 0xB0;mask[2] = (byte) 0xD5;mask[3] = 0x11;
		}
		else if(Pname.equals("RRS1"))
		{
			mask[0] = 0x4F;mask[1] = (byte) 0xC6;mask[2] = 0x73;mask[3] = (byte) 0x98;
		}
		else if(Pname.equals("TPMS1"))
		{
			mask[0] = (byte) 0xB2;mask[1] = 0x17;mask[2] = (byte) 0xA2;mask[3] = 0x59;
		}
		else if(Pname.equals("ACU1"))
		{
			mask[0] = 0x5A;mask[1] = (byte) 0xE4;mask[2] = 0x33;mask[3] = 0x49;
		}
		else if(Pname.equals("PLG1"))
		{
			mask[0] = 0x24;mask[1] = (byte) 0xE2;mask[2] = 0x15;mask[3] = 0x6B;
		}
		else if(Pname.equals("EDR1"))
		{
			mask[0] = (byte) 0xD4;mask[1] = 0x68;mask[2] = (byte) 0xB4;mask[3] = 0x30;
		}
		xy_S401_level1_safekey(mask,Pseed,Pkey);
	}
	private static void xy_S401_level1_safekey(byte[] mask,byte[] Pseed,byte[] Pkey)
	{
		byte [] cal = new byte[4];
		for(int i = 0; i < 4; i ++)
			cal[i] = (byte) (Pseed[i] ^ mask[i]);
		Pkey[0] = (byte) (((cal[3]&0x0F) << 4) | (cal[0] & 0xFF));
		Pkey[1] = (byte) ((cal[1]&0xD8) | ((cal[2] & 0xF0) >>>4));
		Pkey[2] = (byte) ((cal[2]&0xCF) | (cal[0]&0xF0));
		Pkey[3] = (byte) ((cal[3]&0xF0) | ((cal[1] & 0xD0) >>>4));
	}
	public static void hcxy_delphi_1_safekey(byte [] seed,byte [] key)
	{
		byte [] samask = {(byte) 0xFC,0x13,(byte) 0xAD,0x3D};
		byte [] cal = new byte[4];
		cal[0] = (byte) (seed[0] ^ samask[0]);
		cal[1] = (byte) (seed[1] ^ samask[1]);
		cal[2] = (byte) (seed[2] ^ samask[2]);
		cal[3] = (byte) (seed[3] ^ samask[3]);
		key[0] = (byte) ((cal[2]&0x0F) | (cal[2]&0xF0));
		key[1] = (byte) (((cal[0]&0x0F)<<4) | ((cal[1]&0xF0) >> 4));
		key[2] = (byte) ((cal[1]&0xF0) | ((cal[3]&0xF0) >> 4));
		key[3] = (byte) (((cal[0]&0x0F) << 4) | (cal[3]&0x0F));
	}
	public static void hcxy_delphi_cng_safekey(byte [] seed,byte [] key)
	{
		byte [] samask = {0x13,(byte) 0xA3,0x54,0x64};
		byte [] cal = new byte[4];
		cal[0] = (byte) (seed[0] ^ samask[0]);
		cal[1] = (byte) (seed[1] ^ samask[1]);
		cal[2] = (byte) (seed[2] ^ samask[2]);
		cal[3] = (byte) (seed[3] ^ samask[3]);
		key[0] = (byte) ((cal[2]&0x0F) | (cal[2]&0xF0));
		key[1] = (byte) (((cal[0]&0x0F)<<4) | ((cal[1]&0xF0) >> 4));
		key[2] = (byte) ((cal[1]&0xF0) | ((cal[3]&0xF0) >> 4));
		key[3] = (byte) (((cal[0]&0x0F) << 4) | (cal[3]&0x0F));
	}
	public static void hcxy_vin_aecs_old_Safekey(byte[] seed,byte[] key)
	{
		long v0 = (seed[0] & 0xFF) * 0x1000000 + (seed[1] & 0xFF) * 0x10000 + (seed[2] & 0xFF) * 0x100 + (seed[3] & 0xFF);
		long v1 = (~seed[0] & 0xFF) * 0x1000000 + (~seed[1] & 0xFF) * 0x10000 + (~seed[2] & 0xFF) * 0x100 + (~seed[3] & 0xFF);
		long sum = 0;
		long delta = 0x9E3779B9;
		long [] k = {0,0,0,0};
		k[0] =  0xCBC2CE48;
		k[1] =  0x477800DB;
		k[2] =  0xB3E2318C;
		k[3] =  0xD77B6BC1;
		for(int i = 0; i < 2; i ++)
		{
			v0 +=  (((v1 << 4) ^ ((v1 >> 5)& 0x07FFFFFF)) + v1) ^ (sum + k[(int) (sum & 3)]);
			sum += delta;
			v1 +=  (((v0 << 4) ^ ((v0 >> 5)& 0x07FFFFFF)) + v0) ^ (sum + k[(int) ((sum>>11) & 3)]);
		}
		key[0] = (byte) ((v0 >>> 24) & 0xFF);
		key[1] = (byte) ((v0 >>> 16) & 0xFF);
		key[2] = (byte) ((v0 >>> 8) & 0xFF);
		key[3] = (byte) ((v0 >>> 0) & 0xFF);
	}
	public static void hcxy_vin_ling_safekey(byte[] seed,byte[] key)
	{
		long Sd = (seed[0] & 0xFF) * 0x1000000 + (seed[1] & 0xFF) * 0x10000 + (seed[2] & 0xFF) * 0x100 + (seed[3] & 0xFF);
		long K1 = 542712;
		long K2 = 2567;
		long A,B;
		A = (K2 * Sd) + K1;
		B = (K2 * Sd) - K1;
		long Ky = A ^ B;
		key[0] = (byte) ((Ky >>> 24) & 0xFF);
		key[1] = (byte) ((Ky >>> 16) & 0xFF);
		key[2] = (byte) ((Ky >>> 8) & 0xFF);
		key[3] = (byte) ((Ky >>> 0) & 0xFF);
	}
	public static void hcxy_529_abs_safekey(byte[] seed,byte[] key)
	{
		hongyuan_ACU_safekey(seed,key);
	}
	public static void hezhong_safekey(byte[] seed,byte[] key)
	{
		Log.i(TAG, "hezhong_safekey: seed = " + Commonfunc.bytesToHex(seed));
		int TOPBIT = 0x8000;
		int POLYNOM_1 = 0x8408;
		int POLYNOM_2 = 0x8025;
		int BITMASK = 0x0080;
		int INITIAL_REMINDER = 0xFFFE;
		int MSG_LEN = 2; /* seed length in bytes */
		byte [] bSeed = new byte[2];
		short remainder;
		byte n;
		byte i;
		bSeed[0] = seed[0]; /* MSB */
		bSeed[1] = seed[1]; /* LSB */
		remainder = (short) INITIAL_REMINDER;
		for (n = 0; n < MSG_LEN; n++)
		{
			/* Bring the next byte into the remainder. */
			remainder ^= ((bSeed[n]) << 8);

			/* Perform modulo-2 division, a bit at a time. */
			for (i = 0; i < 8; i++)
			{
				/* Try to divide the current data bit. */
				if ((remainder & TOPBIT) != 0)
				{
					if((remainder & BITMASK) != 0)
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_1);
					}
					else
					{
						remainder = (short) ((remainder << 1) ^ POLYNOM_2);
					}
				}
				else
				{
					remainder = (short) (remainder << 1);
				}
			}
		}
		key[0] = (byte) ((remainder >>> 8)&0xFF);
		key[1] = (byte) (remainder & 0xFF);
		Log.i(TAG, "hezhong_safekey: key = " + Commonfunc.bytesToHex(key));
	}
	public static void hozon_S30_safekey11(byte[] seed,byte[] key)
	{
		Log.i(TAG, "hozon_S30_safekey11: seed = " + Commonfunc.bytesToHex(seed));
		int TOPBIT = 0x8000;
		int POLYNOM_1 = 0x9367;
		int POLYNOM_2 = 0x2956;
		int BITMASK = 0x0080;
		int INITIAL_REMINDER = 0xFFFE;
		int MSG_LEN = 2; /* seed length in bytes */
		byte [] bSeed = new byte[2];
		short  remainder;
		byte n;
		byte i;
		bSeed[0] = seed[0]; /* MSB */
		bSeed[1] = seed[1]; /* LSB */
		remainder = (short) INITIAL_REMINDER;
		for (n = 0; n < MSG_LEN; n++)
		{
			/* Bring the next byte into the remainder. */
			remainder ^= ((bSeed[n]) << 8);
			/* Perform modulo-2 division, a bit at a time. */
			for (i = 0; i < 12; i++)
			{
				/* Try to divide the current data bit. */
				if ((remainder & TOPBIT) != 0)
				{
					if((remainder & BITMASK) != 0)
					{
						remainder = (short) ((remainder << 2) ^ POLYNOM_1);
					}
					else
					{
						remainder = (short) ((remainder << 2) ^ POLYNOM_2);
					}
				}
				else
				{
					remainder = (short) (remainder << 1);
				}
			}
		}
		key[0] = (byte) ((remainder >>> 8)&0xFF);
		key[1] = (byte) (remainder & 0xFF);
		Log.i(TAG, "hozon_S30_safekey11: key = " + Commonfunc.bytesToHex(key));
	}

	public static String GetPinCode(String vin){
		byte [] vinChars = new byte[17];
		byte [] acsChar = new byte[17];
		byte []  Chars9 = new byte[9];
		byte []  Chars9temp = new byte[9];
		byte []  Chars5 = new byte[5];
		byte []  Chars4 = new byte[4];
		byte []  Hex4 = new byte[4];
		byte []  Chars2 = new byte[2];
		String  Chars2Hex = "";
		String sb = "";
		byte M;
		vinChars = vin.getBytes();
		for (int i = 0; i < 9; i++) {
			if (i == 8) {
				Chars9[i] = vinChars[i];
			} else {
				acsChar[i] = vinChars[i];
				acsChar[16 - i] = vinChars[16-i];
				Chars9[i] = (byte) (acsChar[i] + acsChar[16 - i]);
			}
		}


		for (int i = 0; i <= Chars9.length / 2; i++) {
			if (i == 4) {
				Chars5[i] = Chars9[i];
			} else {
				Chars9temp[i] = Chars9[i];
				Chars9temp[8 - i] = Chars9[8 - i];
				Chars5[i] = (byte) (Chars9temp[i] ^ Chars9temp[8 - i]);
			}
		}

		M = (byte) ~Chars5[2];

		Chars4[0] = (byte) (Chars5[0] + M);
		Chars4[1] = (byte) (Chars5[1] + M);
		Chars4[2] = (byte) (Chars5[3] + M);
		Chars4[3] = (byte) (Chars5[4] + M);


		sb = Commonfunc.bytesToHexStringP(Chars4,0,4);
		sb = sb.substring(1) + sb.charAt(0);

		Commonfunc.StringToBytes(sb,Hex4,4);

		Chars2[0] = (byte) (Hex4[0] ^ Hex4[2]);
		Chars2[1] = (byte) (Hex4[1] ^ Hex4[3]);


		Chars2Hex = Commonfunc.bytesToHexStringP(Chars2,0,2);
		return hozongetSeedKey(Chars2Hex);
	}

	public static String hozongetSeedKey(String seed) {
		byte [] seedKey = new byte[2];
		Commonfunc.StringToBytes(seed,seedKey,2);
		byte msb = seedKey[0];
		byte lsb = seedKey[1];
		byte [] fanalValue = {18, 52};

		byte [] intXOR = new byte[2];

		byte [] ywtemp = new byte[2];
		//先移位运算
		ywtemp[0] = (byte) ((((lsb >>> 1)&0x01) << 7) + (((msb >>> 6)&0x01) << 6) + (((msb >>> 7)&0x01) << 5) + (((msb >>> 4)&0x01) << 4) +
							(((msb >>> 5)&0x01) << 3) + (((msb >>> 2)&0x01) << 2) + (((msb >>> 3)&0x01) << 1) + (((msb >>> 0)&0x01) << 0));
		ywtemp[1] = (byte) ((((msb >>> 1)&0x01) << 7) + (((lsb >>> 6)&0x01) << 6) + (((lsb >>> 7)&0x01) << 5) + (((lsb >>> 4)&0x01) << 4) +
							(((lsb >>> 5)&0x01) << 3) + (((lsb >>> 2)&0x01) << 2) + (((lsb >>> 3)&0x01) << 1) + (((lsb >>> 0)&0x01) << 0));


		intXOR[0] = (byte) (ywtemp[0] ^ fanalValue[0]);
		intXOR[1] = (byte) (ywtemp[1] ^ fanalValue[1]);



		seedKey[0] = (byte) ~intXOR[0];
		seedKey[1] = (byte) ~intXOR[1];

		if ((seedKey[0]&0xFF) == 0xFF && (seedKey[1]&0xFF) == 0xFF) {
			seedKey[0] = (byte) 0xAB;
			seedKey[1] = (byte) 0xCD;
		}
		else if ((seedKey[0]&0xFF) == 0x00 && (seedKey[1]&0xFF) == 0x00) {
			seedKey[0] = 0x12;
			seedKey[1] = 0x34;
		}
		else if ((seedKey[0]&0xFF) == 0xFF) {
			seedKey[0] = (byte) 0xFE;
		}
		else if ((seedKey[1]&0xFF) == 0xFF) {
			seedKey[1] = (byte) 0xFE;
		}
		if ((seedKey[0]&0xFF) == 0x00) {
			seedKey[0] = 0x01;
		}
		if ((seedKey[1]&0xFF) == 0x00) {
			seedKey[1] = 0x01;
		}

		return Commonfunc.bytesToHexStringP(seedKey,0,2);
	}
	public  static String genHozonESK(String vin) {
		byte [] WMI = vin.substring(0, 3).getBytes();
		byte [] VDS = vin.substring(3, 8).getBytes();
		byte CRC = (byte) vin.charAt(8);
		byte motor_type = (byte) vin.charAt(9);
		byte factory = (byte) vin.charAt(10);
		byte [] serial = vin.substring(11, 17).getBytes();
		byte [] tmp_arr0 = new byte[6];
		byte [] tmp_arr1 = new byte[6];
		byte [] tmp_arr2 = new byte[6];
		byte [] datask = new byte[16];

		for (int i = 0; i < 3; i++) {
			tmp_arr1[i] = WMI[i];
			tmp_arr2[i] = (byte) (WMI[i]^0xFF);
		}

		tmp_arr1[3] = CRC;
		tmp_arr2[3] = (byte) (CRC^0xFF);

		tmp_arr1[4] = motor_type;
		tmp_arr2[4] = (byte) (motor_type^0xFF);

		tmp_arr1[5] = factory;
		tmp_arr2[5] = (byte) (factory^0xFF);

		byte tmp_flg = 0;
		for (int i = 0; i < 6; i++) {
			tmp_arr0[i] = tmp_arr1[i];
			datask[i] = (byte) (tmp_arr1[i] ^ serial[i]);
			datask[6 + i] = (byte) (tmp_arr2[i] ^ ((serial[i]&0xFF) + (tmp_arr0[i]&0xFF) + tmp_flg));
			if ((tmp_arr2[i]&0xFF) + (tmp_arr0[i]&0xFF) <= 255) {
				tmp_flg = 1;
			} else {
				tmp_flg = 0;
			}
		}

		for (int i = 0; i < 4; i++) {
			datask[12 + i] = (byte) ((VDS[1 + i] ^ 0xff) ^ VDS[i]);
		}
		return Commonfunc.bytesToHexStringP(datask,0,16);
	}
}
	